package com.nsoft.utils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;

import com.nsoft.utils.Constant;

import com.nsoft.objects.BookItem;
import com.nsoft.objects.BookList;

public class engine {
	private static String engineServer=Constant.EMPTY;
	private static String engineParams=Constant.EMPTY;
	private static ArrayList<BookItem> bookList=
						new ArrayList<BookItem>();
	private static ArrayList<Bitmap> thumbList=
							new ArrayList<Bitmap>();
	
	public static String getEngineServer() {
		return engineServer;
	}
	public static void setEngineServer(String engineServer) {
		engine.engineServer = engineServer;
	}

	public static String getEngineParams() {
		return engineParams;
	}
	public static void setEngineParams(String engineParams) {
		engine.engineParams = engineParams;
	}
	
	public static Bitmap[] getThumbList(){
		return thumbList.toArray(new Bitmap[]{});
	}
	public static void addBitmapToThumbList(Bitmap bmp){
		thumbList.add(bmp);
	}
	
	public static BookItem getBookItem(int idx){
		return bookList.get(idx);
	}
	
	public static void addBookItem(BookItem book){
		bookList.add(book);
	}
	
	public static void removeBookItem(int idx){
		bookList.remove(idx);
	}
	
	public static void removeAllBooks(){
		bookList.clear();
	}
	
	public static String[] getBookTitles(){
		if (bookList==null || bookList.size()==0){
			return new String[0]; 
		}
		
		int numOfBooks=bookList.size();
		String[] titles=new String[numOfBooks];
		for (int i=0;i<numOfBooks;i++){
			titles[i]=bookList.get(i).getContentName();
		}
		return titles;
	}
	
	public static String[] getBookThumbImagePaths(){
		if (bookList==null || bookList.size()==0){
			return new String[0]; 
		}
		
		int numOfBooks=bookList.size();
		String[] thumbImgs=new String[numOfBooks];
		for (int i=0;i<numOfBooks;i++){
			thumbImgs[i]=bookList.get(i).getImgPath();
		}
		return thumbImgs;
	}
	
	public static void getBookThumbBitmaps(){
		if (bookList==null || bookList.size()==0){
			return;
		}
		int thumbSize=bookList.size();
		Bitmap bmp=null;
		for (int i=0;i<thumbSize;i++){
			bmp=getBitmapFromURL(
					bookList.get(i).getImgPath());
			thumbList.add(bmp);
		}
	}
	
	public static void getBookThumbBitmapsFromHistory(){
		if (bookList==null || bookList.size()==0){
			return;
		}
		int thumbSize=bookList.size();
		Bitmap bmp=null;
		for (int i=0;i<thumbSize;i++){
			bmp=getBitmapFromFile(
					bookList.get(i).getImgPath());
			thumbList.add(bmp);
		}
	}
	
	public static boolean getBookListFromHistory()
							throws Exception{
		return getBookListFromXml();
	}
	
	public static void getBookListFromServer() 
							throws Exception{
		getBookListFromServer(
			getEngineServer(),getEngineParams());
	}
	
	private static void getBookListFromServer(
			String server,String params) throws Exception{
		bookList=new ArrayList<BookItem>();
		bookList.clear();
		
		String thumbPath=utils.getThumbPath();
		String url=server+params;
		InputStream is=new URL(url).openStream();
		
		DocumentBuilderFactory docBuilderFactory = 
					DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = 
        		docBuilderFactory.newDocumentBuilder();
		Document doc=docBuilder.parse(is);
        
        NodeList list=doc.getElementsByTagName(
        			Constant.xml.XML_TAG_CONTENT);
        NodeList c_nodes=null;
        BookItem book=null;
        String nodeCont,nodeName,savedImgPath;
        boolean isBookGotBugs=false;
		for (int i=0;i<list.getLength();i++){
			c_nodes=list.item(i).getChildNodes();
			book=new BookItem();
			isBookGotBugs=false;
			
			for (int j=0;j<c_nodes.getLength();j++){
				nodeCont=c_nodes.item(j).getTextContent();
				nodeName=c_nodes.item(j).getNodeName();
				if (nodeName.equalsIgnoreCase(
						Constant.xml.XML_TAG_CONTENTNAME)){
					if (nodeCont.equals(Constant.EMPTY)){
						isBookGotBugs=true;
						break;
					}
					book.setContentName(nodeCont);
				}else if (nodeName.equalsIgnoreCase(
						Constant.xml.XML_TAG_CONTENTID)){
					book.setContentId(nodeCont);
				}else if (nodeName.equalsIgnoreCase(
						Constant.xml.XML_TAG_DOWNLOADPATH)){
					book.setDownloadPath(nodeCont);
				}else if (nodeName.equalsIgnoreCase(
						Constant.xml.XML_TAG_IMGPATH)){
					savedImgPath=saveThumbToStorage(
								nodeCont,thumbPath);
					if (savedImgPath.equals(Constant.EMPTY)){
						isBookGotBugs=true;
						break;
					}
					book.setImgPath(savedImgPath);
				}else if (nodeName.equalsIgnoreCase(
						Constant.xml.XML_TAG_VERSION)){
					book.setVersion(nodeCont);
				}else if (nodeName.equalsIgnoreCase(
						Constant.xml.XML_TAG_STATE)){
					book.setState(nodeCont);
				}else if (nodeName.equalsIgnoreCase(
						Constant.xml.XML_TAG_REDOWNLOAD)){
					book.setReDownload(nodeCont);
				}
			}
			if (!isBookGotBugs){
				bookList.add(book);
			}else{
				isBookGotBugs=false;
			}
		}
		
		saveBookListToXml();
	}

	private static boolean getBookListFromXml()
						throws Exception{
		String xmlHistoryFile=utils.getHistoryListFile();
		try{
			BookList bookListContainer=
				(BookList)utils.decodeXml(
						new File(xmlHistoryFile),
						BookList.class);
			bookList=bookListContainer.getBookItems();
			return true;
		}catch(Exception e){
			Log.v("engine.saveBookListToXml()",
				e.getClass().toString()+": "+e.getMessage());
			throw e;
		}
	}
	
	private static String saveBookListToXml() 
						throws Exception {
		String xmlFilePath=utils.getHistoryListFile();
		try{
			BookList bookListContainer=new BookList();
			bookListContainer.setBookItems(bookList);
			utils.encodeXml(bookListContainer,
							new File(xmlFilePath));
			return xmlFilePath;
		}catch(Exception e){
			Log.v("engine.saveBookListToXml()",
				e.getClass().toString()+": "+e.getMessage());
			throw e;
		}
	}
	
	private static String saveThumbToStorage(
						String src,String outPath){
		InputStream input=null;
		OutputStream output=null;
		try{
			URL url=new URL(src);
			String fileName=src.substring(
					src.lastIndexOf(Constant.PATH_SPLITTER)+1);
			String outputFilePath=outPath+
					Constant.PATH_SPLITTER+fileName;
			
			HttpURLConnection connection=
	        		(HttpURLConnection)url.openConnection();
	        connection.setDoInput(true);
	        connection.connect();
	        input=connection.getInputStream();
	        output=new FileOutputStream(outputFilePath,false);
	        
	        byte[] buff=new byte[1024];
	        int bytesRead=0;
	        while((bytesRead=input.read(buff))!=-1){
	        	output.write(buff,0,bytesRead);
	        }
	        output.flush();
			return outputFilePath;
		}catch(IOException e){
			Log.v("engine.saveThumbToStorage()",
		    		"["+e.getClass().toString()+"] "+e.getMessage());
		    	return Constant.EMPTY;
		}finally{
			try {
				if (input!=null){
					input.close();
				}
				if (output!=null){
					output.close();
				}
			}catch(IOException e){ }
		}
	}
	
	private static Bitmap getBitmapFromFile(String src){
		return BitmapFactory.decodeFile(src);
	}
	
	private static Bitmap getBitmapFromURL(String src){
		try {
	        URL url=new URL(src);
	        HttpURLConnection connection=
	        		(HttpURLConnection)url.openConnection();
	        connection.setDoInput(true);
	        connection.connect();
	        InputStream input=connection.getInputStream();
	        Bitmap myBitmap=BitmapFactory.decodeStream(input);
	        return myBitmap;
	    }catch(IOException e){
	    	Log.v("engine.getBitmapFromURL()",
	    		"["+e.getClass().toString()+"] "+e.getMessage());
	    	return null;
	    }
	}

}
